import { BlockComponentTypes, BlockVolume } from "@minecraft/server";
import { Dimensions } from "@sapi-game/constants";
import { Game, GameComponent } from "@sapi-game/main";
import { Duration } from "@sapi-game/utils";
import {
    EleDirection,
    Elevator,
    ElevatorEvent,
    ElevatorEventType,
    ElevatorState,
} from "./elevator";
import { eleMainState } from "../state";
import { ElevatorDoorComponent } from "./elevatorDoor";

/**显示相关 */
export class ElevatorViewComponent extends GameComponent<eleMainState> {
    get utils() {
        return this.context.utils;
    }

    override onAttach(): void {
        //订阅事件
        this.state.eleList.forEach((e) =>
            e.onEvent((event) => {
                this.handleEvent(e, event);
            })
        );
        //周期更新牌子
        this.subscribe(
            Game.events.interval,
            () => {
                this.state.eleList.forEach((e) => {
                    this.updateSign(e, e.getState());
                });
            },
            new Duration(10)
        );
    }
    /**处理电梯事件 */
    handleEvent(elevator: Elevator, event: ElevatorEvent) {
        switch (event.type) {
            case ElevatorEventType.Open:
                this.OpenOrCloseDoor(elevator, event.type);
                break;
            case ElevatorEventType.Move:
                this.managePlayersInElevator(elevator, event);
                break;
            case ElevatorEventType.Close:
                this.OpenOrCloseDoor(elevator, event.type);
                break;
            case ElevatorEventType.Moving:
                this.managePlayersInElevator(elevator, event);
                break;
        }
    }

    managePlayersInElevator(elevator: Elevator, event: ElevatorEvent) {
        const floorY = this.utils.calcFloorY(event.state.floor);
        const players = elevator.config.region.getPlayersInRegion();
        for (const p of players) {
            p.onScreenDisplay.setActionBar(
                `电梯${
                    event.state.direction === EleDirection.Up ? "上行" : "下行"
                } 当前第${event.state.floor}层`
            );
            if (event.type == ElevatorEventType.Moving) return;
            const loc = p.location;
            const Y = loc.y + this.context.FloorHeight;
            p.teleport({
                x: loc.x,
                y:
                    Y >= floorY && Y < floorY + this.context.FloorHeight
                        ? Y
                        : floorY,
                z: loc.z,
            });
        }
    }

    /**更新每一层的显示 */
    updateSign(elevator: Elevator, state: ElevatorState) {
        const baseLoc = elevator.baseLoc;
        for (let floor = 1; floor <= elevator.config.maxFloor; floor++) {
            const floorY = this.utils.calcFloorY(floor);
            const sign = Dimensions.Overworld.getBlock({
                x: baseLoc.x + 3,
                y: floorY + 1,
                z: baseLoc.z - 3,
            })?.getComponent(BlockComponentTypes.Sign);
            const innerSign = Dimensions.Overworld.getBlock({
                x: baseLoc.x,
                y: floorY + 2,
                z: baseLoc.z,
            })?.getComponent(BlockComponentTypes.Sign);
            const text = `${state.floor}\n${
                state.direction == EleDirection.Down
                    ? "↓"
                    : state.direction == EleDirection.Up
                    ? "↑"
                    : "-"
            }`;
            if (sign) sign.setText(text);
            if (innerSign) innerSign.setText(text);
        }
    }

    OpenOrCloseDoor(elevator: Elevator, type: ElevatorEventType) {
        const isOpen = type === ElevatorEventType.Open;
        elevator.config.region.runCommandOnPlayers(
            `title @s actionbar 电梯${isOpen ? "开门" : "关门"}`
        );
        const door = this.state.getComponent(ElevatorDoorComponent);
        door.OpenOrCloseDoor(elevator, isOpen);
    }
}
